package responsehandler;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.sql.Connection;

import twitter4j.internal.org.json.JSONArray;
import twitter4j.internal.org.json.JSONException;
import twitter4j.internal.org.json.JSONObject;

import commands.GetNewMessagesCommand;
import commands.GetTimelineTagDataCommand;
import commands.GetTopOwnersCommand;
import commands.GetTopTagsCommand;
import commands.GetTwitterQueryCommand;
import commands.GetTwitterStreamCommand;
import database.models.MessageModel;
import database.models.MessageOwnerModel;
import database.models.TagModel;

/**
 * ClientThread Class where commands from the user are handled.
 * @author Project group 9
 *
 */
public class ClientThread implements Runnable {

	private Socket socket;
	
	private MessageOwnerModel messageOwnerModel;
	private MessageModel messageModel;
	private TagModel tagModel;

	/**
	 * Makes sure that the socket of the clientthread is the same as the clients
	 * socket.
	 * 
	 * @param socket
	 *            Socket from the client
	 * @param con
	 *            Connection with the db
	 */
	public ClientThread(Socket socket, Connection con) {
		this.socket = socket;
		this.messageOwnerModel = new MessageOwnerModel(con);
		this.messageModel = new MessageModel(con, messageOwnerModel);
		this.tagModel = new TagModel(con, messageModel);
	}
	
	/**
	 * Run method. Invoked on start().
	 */
	@Override
	public void run() {
		try {
			while (true) {
				BufferedReader br = new BufferedReader(new InputStreamReader(
						socket.getInputStream()));
				BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
						socket.getOutputStream()));
				String line = "";
				String output = "";

				while ((line = br.readLine()) != null) {
					try {
						JSONArray array = new JSONArray(line);
						for (int i = 0; i < array.length(); i++) {
							JSONObject jsonObject = (JSONObject) array.get(i);
							if (jsonObject.has("getTopTags")) {
								GetTopTagsCommand c = new GetTopTagsCommand(jsonObject, tagModel);
								output = c.execute();
							} else if (jsonObject.has("getTimelineTagData")) {
								GetTimelineTagDataCommand c = new GetTimelineTagDataCommand(jsonObject, tagModel);
								output = c.execute();
							} else if (jsonObject.has("getNewMessages")) {
								GetNewMessagesCommand c = new GetNewMessagesCommand(jsonObject, messageModel);
								output = c.execute();
							} else if (jsonObject.has("getTwitterStream")) {
								GetTwitterStreamCommand c = new GetTwitterStreamCommand(jsonObject, messageModel);
								output = c.execute();
							} else if (jsonObject.has("getTwitterQuery")) { 
								GetTwitterQueryCommand c = new GetTwitterQueryCommand(jsonObject);
								output = c.execute();
							} else if (jsonObject.has("getTopOwners")) { 
								GetTopOwnersCommand c = new GetTopOwnersCommand(jsonObject, messageOwnerModel);
								output = c.execute();
							}
						}
					} catch (JSONException e) {
						e.printStackTrace();
					}
					
					bw.write(output + "\n");
					bw.flush();
				}

				// Closing streams and the current socket (not the listening socket!)
				bw.close();
				br.close();
				socket.close();
			}
		} catch (IOException e) {
			System.out.println("Socket closed");
		}
	}
}